#!/usr/bin/env python
# -*- coding: utf-8 -*-
#===============================================================================
# Copyright 2011 zod.yslin
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 
# Author: zod.yslin
# Email: 
# File Name: return.py
# Description: 
#   They always return a value. However, if no return value is specified, 
#   or you don't use the return keyword, Python automatically returns the value None.
#
#   lists, tuples, and dictionaries are basic types they can be returned.
#   functions are data in Python, not just special labels for code blocks
#   (or whatever they are in C/C++). 
#
#   Python passes all arguments using "pass by reference".
# Edit History: 
#   2011-09-14    File created.
#===============================================================================
# We can use append here
def map( fun, list ):
    nlist = []
    for item in list:
        nlist.append( fun( item ) )
    return nlist
# But here we have to use concatenation, or the + operator for lists.
def rmap ( fun, list ):
    if list == []:
        return []
    else:
        return [fun( list[0] )] + rmap( fun, list[1:] )

# Make a sample test function
def increment(x):
    return x+1

# Test them out!
print(map( increment, [1,2,3,4,5] ))
# should return [2,3,4,5,6]
print(map( increment, [1,2,3,4,5] ) == rmap( increment, [1,2,3,4,5] ))
# There outputs should be the same!

"""
Let's assume that I have a C++ code in which I want to return 3 values. There are a number of ways I could return

-1,0,1
from C++.
Possible Method I:

void return3values( int &a, int &b, int &c ) { a = -1; b = 0; c = 1; }
Possible Method II:

void returnArray( int *array ) { array[0] = -1; array[1] = 0; array[2] = 1; }
"""

# multiple-returns.py
a, b, c = 0, 0, 0
def getabc():
    a = "Hello"
    b = "World"
    c = "!"
    return a,b,c #defines a tuple on the fly

def gettuple():
    a,b,c = 1,2,3 # Notice the similarities between this and getabc?
    return (a,b,c)

def getlist():
    a,b,c = (3,4),(4,5),(5,6)
    return [a,b,c]

# These all work, as amazing as it seems.
# So multiple assignment is actually quite easy.
a,b,c = getabc()
print(type(getabc()))
print(a, b, c)
d,e,f = gettuple()
print(type(gettuple()))
print(d, e, f)
g,h,i = getlist()
print(type(getlist()))
print(g, h, i)
